<{extend name="Public:public" /}>

<{block name="title"}>单元测试<{/block}>

<{block name="content"}> 
<div class="content guide with-sidebar unit-testing-guide">
  
    
      <div id="ad">
  <!-- <script
    async
    type="text/javascript"
    src="//cdn.carbonads.com/carbon.js?serve=CKYIK2QU&placement=vuejsorg"
    id="_carbonads_js">
  </script> -->
  <a href="https://studio.qcloud.coding.net/campaign/favorite-plugins/?utm_source=vue.js&amp;utm_content=ad1116" target="_blank">
    <img src="/images/coding-net-ad.jpg">
  </a>
</div>

    
  
  
    <h1>单元测试</h1>
  
  
    <h2 id="配置和工具"><a href="#配置和工具" class="headerlink" title="配置和工具" data-scroll="">配置和工具</a></h2><p>任何兼容基于模块的构建系统都可以正常使用，但如果你需要一个具体的建议，可以使用 <a href="https://karma-runner.github.io" target="_blank" rel="noopener">Karma</a> 进行自动化测试。它有很多社区版的插件，包括对 <a href="https://github.com/webpack/karma-webpack" target="_blank" rel="noopener">Webpack</a> 和 <a href="https://github.com/Nikku/karma-browserify" target="_blank" rel="noopener">Browserify</a> 的支持。更多详细的安装步骤，请参考各项目的安装文档，通过这些 Karma 配置的例子可以快速帮助你上手 (<a href="https://github.com/vuejs-templates/webpack/blob/master/template/test/unit/karma.conf.js" target="_blank" rel="noopener">Webpack</a> 配置，<a href="https://github.com/vuejs-templates/browserify/blob/master/template/karma.conf.js" target="_blank" rel="noopener">Browserify</a> 配置)。</p>
<h2 id="简单的断言"><a href="#简单的断言" class="headerlink" title="简单的断言" data-scroll="">简单的断言</a></h2><p>你不必为了可测性在组件中做任何特殊的操作，导出原始设置就可以了：</p>
<figure class="highlight html"><table><tbody><tr><td class="code"><pre><span class="line"><span class="tag">&lt;<span class="name">template</span>&gt;</span></span><br><span class="line">  <span class="tag">&lt;<span class="name">span</span>&gt;</span>{{ message }}<span class="tag">&lt;/<span class="name">span</span>&gt;</span></span><br><span class="line"><span class="tag">&lt;/<span class="name">template</span>&gt;</span></span><br><span class="line"></span><br><span class="line"><span class="tag">&lt;<span class="name">script</span>&gt;</span><span class="undefined"></span></span><br><span class="line"><span class="javascript">  <span class="keyword">export</span> <span class="keyword">default</span> {</span></span><br><span class="line"><span class="undefined">    data () {</span></span><br><span class="line"><span class="javascript">      <span class="keyword">return</span> {</span></span><br><span class="line"><span class="javascript">        message: <span class="string">'hello!'</span></span></span><br><span class="line"><span class="undefined">      }</span></span><br><span class="line"><span class="undefined">    },</span></span><br><span class="line"><span class="undefined">    created () {</span></span><br><span class="line"><span class="javascript">      <span class="keyword">this</span>.message = <span class="string">'bye!'</span></span></span><br><span class="line"><span class="undefined">    }</span></span><br><span class="line"><span class="undefined">  }</span></span><br><span class="line"><span class="undefined"></span><span class="tag">&lt;/<span class="name">script</span>&gt;</span></span><br></pre></td></tr></tbody></table></figure>
<p>然后随着 Vue 导入组件的选项，你可以使用许多常见的断言：</p>
<figure class="highlight js"><table><tbody><tr><td class="code"><pre><span class="line"><span class="comment">// 导入 Vue.js 和组件，进行测试</span></span><br><span class="line"><span class="keyword">import</span> Vue <span class="keyword">from</span> <span class="string">'vue'</span></span><br><span class="line"><span class="keyword">import</span> MyComponent <span class="keyword">from</span> <span class="string">'path/to/MyComponent.vue'</span></span><br><span class="line"></span><br><span class="line"><span class="comment">// 这里是一些 Jasmine 2.0 的测试，你也可以使用你喜欢的任何断言库或测试工具。</span></span><br><span class="line"></span><br><span class="line">describe(<span class="string">'MyComponent'</span>, () =&gt; {</span><br><span class="line">  <span class="comment">// 检查原始组件选项</span></span><br><span class="line">  it(<span class="string">'has a created hook'</span>, () =&gt; {</span><br><span class="line">    expect(<span class="keyword">typeof</span> MyComponent.created).toBe(<span class="string">'function'</span>)</span><br><span class="line">  })</span><br><span class="line"></span><br><span class="line">  <span class="comment">// 评估原始组件选项中的函数的结果</span></span><br><span class="line">  it(<span class="string">'sets the correct default data'</span>, () =&gt; {</span><br><span class="line">    expect(<span class="keyword">typeof</span> MyComponent.data).toBe(<span class="string">'function'</span>)</span><br><span class="line">    <span class="keyword">const</span> defaultData = MyComponent.data()</span><br><span class="line">    expect(defaultData.message).toBe(<span class="string">'hello!'</span>)</span><br><span class="line">  })</span><br><span class="line"></span><br><span class="line">  <span class="comment">// 检查 mount 中的组件实例</span></span><br><span class="line">  it(<span class="string">'correctly sets the message when created'</span>, () =&gt; {</span><br><span class="line">    <span class="keyword">const</span> vm = <span class="keyword">new</span> Vue(MyComponent).$mount()</span><br><span class="line">    expect(vm.message).toBe(<span class="string">'bye!'</span>)</span><br><span class="line">  })</span><br><span class="line"></span><br><span class="line">  <span class="comment">// 创建一个实例并检查渲染输出</span></span><br><span class="line">  it(<span class="string">'renders the correct message'</span>, () =&gt; {</span><br><span class="line">    <span class="keyword">const</span> Constructor = Vue.extend(MyComponent)</span><br><span class="line">    <span class="keyword">const</span> vm = <span class="keyword">new</span> Constructor().$mount()</span><br><span class="line">    expect(vm.$el.textContent).toBe(<span class="string">'bye!'</span>)</span><br><span class="line">  })</span><br><span class="line">})</span><br></pre></td></tr></tbody></table></figure>
<h2 id="编写可被测试的组件"><a href="#编写可被测试的组件" class="headerlink" title="编写可被测试的组件" data-scroll="">编写可被测试的组件</a></h2><p>很多组件的渲染输出由它的 props 决定。事实上，如果一个组件的渲染输出完全取决于它的 props，那么它会让测试变得简单，就好像断言不同参数的纯函数的返回值。看下面这个例子：</p>
<figure class="highlight html"><table><tbody><tr><td class="code"><pre><span class="line"><span class="tag">&lt;<span class="name">template</span>&gt;</span></span><br><span class="line">  <span class="tag">&lt;<span class="name">p</span>&gt;</span>{{ msg }}<span class="tag">&lt;/<span class="name">p</span>&gt;</span></span><br><span class="line"><span class="tag">&lt;/<span class="name">template</span>&gt;</span></span><br><span class="line"></span><br><span class="line"><span class="tag">&lt;<span class="name">script</span>&gt;</span><span class="undefined"></span></span><br><span class="line"><span class="javascript">  <span class="keyword">export</span> <span class="keyword">default</span> {</span></span><br><span class="line"><span class="javascript">    props: [<span class="string">'msg'</span>]</span></span><br><span class="line"><span class="undefined">  }</span></span><br><span class="line"><span class="undefined"></span><span class="tag">&lt;/<span class="name">script</span>&gt;</span></span><br></pre></td></tr></tbody></table></figure>
<p>你可以在不同的 props 中，通过 <code>propsData</code> 选项断言它的渲染输出：</p>
<figure class="highlight js"><table><tbody><tr><td class="code"><pre><span class="line"><span class="keyword">import</span> Vue <span class="keyword">from</span> <span class="string">'vue'</span></span><br><span class="line"><span class="keyword">import</span> MyComponent <span class="keyword">from</span> <span class="string">'./MyComponent.vue'</span></span><br><span class="line"></span><br><span class="line"><span class="comment">// 挂载元素并返回已渲染的文本的工具函数</span></span><br><span class="line"><span class="function"><span class="keyword">function</span> <span class="title">getRenderedText</span> (<span class="params">Component, propsData</span>) </span>{</span><br><span class="line">  <span class="keyword">const</span> Constructor = Vue.extend(Component)</span><br><span class="line">  <span class="keyword">const</span> vm = <span class="keyword">new</span> Constructor({ <span class="attr">propsData</span>: propsData }).$mount()</span><br><span class="line">  <span class="keyword">return</span> vm.$el.textContent</span><br><span class="line">}</span><br><span class="line"></span><br><span class="line">describe(<span class="string">'MyComponent'</span>, () =&gt; {</span><br><span class="line">  it(<span class="string">'renders correctly with different props'</span>, () =&gt; {</span><br><span class="line">    expect(getRenderedText(MyComponent, {</span><br><span class="line">      msg: <span class="string">'Hello'</span></span><br><span class="line">    })).toBe(<span class="string">'Hello'</span>)</span><br><span class="line"></span><br><span class="line">    expect(getRenderedText(MyComponent, {</span><br><span class="line">      msg: <span class="string">'Bye'</span></span><br><span class="line">    })).toBe(<span class="string">'Bye'</span>)</span><br><span class="line">  })</span><br><span class="line">})</span><br></pre></td></tr></tbody></table></figure>
<h2 id="断言异步更新"><a href="#断言异步更新" class="headerlink" title="断言异步更新" data-scroll="">断言异步更新</a></h2><p>由于 Vue 进行 <a href="reactivity.html#异步更新队列">异步更新 DOM</a> 的情况，一些依赖 DOM 更新结果的断言必须在 <code>Vue.nextTick</code> 回调中进行：</p>
<figure class="highlight js"><table><tbody><tr><td class="code"><pre><span class="line"><span class="comment">// 在状态更新后检查生成的 HTML</span></span><br><span class="line">it(<span class="string">'updates the rendered message when vm.message updates'</span>, done =&gt; {</span><br><span class="line">  <span class="keyword">const</span> vm = <span class="keyword">new</span> Vue(MyComponent).$mount()</span><br><span class="line">  vm.message = <span class="string">'foo'</span></span><br><span class="line"></span><br><span class="line">  <span class="comment">// 在状态改变后和断言 DOM 更新前等待一刻</span></span><br><span class="line">  Vue.nextTick(<span class="function"><span class="params">()</span> =&gt;</span> {</span><br><span class="line">    expect(vm.$el.textContent).toBe(<span class="string">'foo'</span>)</span><br><span class="line">    done()</span><br><span class="line">  })</span><br><span class="line">})</span><br></pre></td></tr></tbody></table></figure>
<p>我们计划做一个通用的测试工具集，让不同策略的渲染输出 (例如忽略子组件的基本渲染) 和断言变得更简单。</p>
<p>关于更深入的 Vue 单元测试的内容，请移步 <a href="https://vue-test-utils.vuejs.org/zh/" target="_blank" rel="noopener">Vue Test Utils</a> 以及我们关于 <a href="../cookbook/unit-testing-vue-components.html">Vue 组件的单元测试</a>的 cookbook 文章。</p>

  
  
    <div class="guide-links">
      
      
        <span>← <a href="/v2/guide/single-file-components.html">单文件组件</a></span>
      
      
      
        <span style="float: right;"><a href="/v2/guide/typescript.html">TypeScript 支持</a> →</span>
      
    </div>
  
  <div class="footer">
      <script src="//m.servedby-buysellads.com/monetization.js" type="text/javascript"></script>
<div class="bsa-cpc"></div>
<script>
  (function(){
    if(typeof _bsa !== 'undefined' && _bsa) {
    _bsa.init('default', 'CKYD62QM', 'placement:vuejsorg', {
      target: '.bsa-cpc',
      align: 'horizontal',
      disable_css: 'true'
    });
      }
  })();
</script>

    发现错误？想参与编辑？
    <a href="https://github.com/vuejs/cn.vuejs.org/blob/master/src/v2/guide/unit-testing.md" target="_blank">
      在 GitHub 上编辑此页！
    </a>
  </div>
</div>
<{/block}>
